package cn.oatn;

import java.io.IOException;
import java.util.Arrays;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class T1004_ASM_View {

    public static void test() throws IOException {
        ClassReader cr = new ClassReader("cn.oatn.MyRunnable"); // 使用ClassReader读取字节码
        cr.accept(new ClassVisitor(Opcodes.ASM9) {
            @Override
            public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
                System.out.printf("Now visit class start, classFileVersion: %s, access:%s, className: %s, signature:%s, superClass:%s, interfaces:%s%n", version, access, name, signature, superName, Arrays.toString(interfaces));
            }

            @Override
            public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
                System.out.printf("Now visit field, access:%s, name:%s, descriptor:%s, signature:%s, value:%s%n", access, name, descriptor, signature, value);
                return new FieldVisitor(Opcodes.ASM9) {
                    @Override
                    public void visitAttribute(Attribute attribute) {
                        System.out.println("- Attribute: " + attribute);
                    }

                    @Override
                    public void visitEnd() {
                        System.out.printf("-- Now visit field %s finished%n", name);
                    }
                };
            }

            @Override
            public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
                System.out.printf("Now visit method, access:%s, name:%s, descriptor:%s, signature:%s, exceptions:%s%n", access, name, descriptor, signature, Arrays.toString(exceptions));
                return new MethodVisitor(Opcodes.ASM9) {
                    @Override
                    public void visitParameter(String pname, int access) {
                        System.out.printf("- Method:%s Parameter:%s%n", name, pname);
                    }

                    @Override
                    public void visitCode() {
                        System.out.printf("- Method:%s code start%n", name);
                    }

                    @Override
                    public void visitMethodInsn(int opcode, String owner, String mname, String descriptor, boolean isInterface) {
                        System.out.printf("- Method:%s, invoke other method %s%s%n", name, owner, mname);
                    }

                    @Override
                    public void visitLineNumber(int line, Label start) {
                        System.out.printf("- Method:%s, current line number %s%n", name, line);
                    }

                    @Override
                    public void visitMaxs(int maxStack, int maxLocals) {
                        System.out.printf("- Method:%s, maxStack:%s, maxLocals:%s%n", name, maxStack, maxLocals);
                    }

                    @Override
                    public void visitEnd() {
                        System.out.printf("- Method:%s, visit finished%n", name);
                    }
                };
            }

            @Override
            public void visitEnd() {
                System.out.println("Now visit class finished");
            }


        }, 0);
    }


}
